home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_11 / phillip2 / edge.c < prev    next >
C/C++ Source or Header  |  1993-05-14  |  19KB  |  770 lines

  1.  
  2.  
  3.        /***********************************************
  4.        *
  5.        *       file d:\cips\edge.c
  6.        *
  7.        *       Functions: This file contains
  8.        *          detect_edges
  9.        *          setup_masks
  10.        *          get_edge_options
  11.        *          perform_convolution
  12.        *          quick_edge
  13.        *          fix_edges
  14.        *
  15.        *       Purpose:
  16.        *          These functions implement several
  17.        *          types of basic edge detection.
  18.        *
  19.        *       External Calls:
  20.        *          wtiff.c - round_off_image_size
  21.        *                    create_file_if_needed
  22.        *                    write_array_into_tiff_image
  23.        *          tiff.c - read_tiff_header
  24.        *          rtiff.c - read_tiff_image
  25.        *          numcvrt.c - get_integer
  26.        *
  27.        *
  28.        *       Modifications:
  29.        *          27 January 1991 - created
  30.        *          27 December 1992 - Fixed an error in
  31.        *              how I did the 8 direction edge
  32.        *              detectors.  I was only detecting
  33.        *              edges in the last (the 7)
  34.        *              direction.  I fixed this by
  35.        *              setting the out_image to the sum
  36.        *              only if the sum was greater than
  37.        *              the out_image.  This is in the
  38.        *              function perform_convolution.
  39.        *
  40.        *************************************************/
  41.  
  42. #include "cips.h"
  43.  
  44.  
  45.  
  46.  
  47.  
  48. short quick_mask[3][3] =  {
  49.        {-1,  0, -1},
  50.        { 0,  4,  0},
  51.        {-1,  0, -1} };
  52.  
  53.  
  54.    /***************************
  55.    *
  56.    *   Directions for the masks
  57.    *  3 2 1
  58.    *  4 x 0
  59.    *  5 6 7
  60.    *
  61.    ****************************/
  62.  
  63.    /* masks for kirsch operator */
  64. short kirsch_mask_0[3][3] =  {
  65.        { 5,  5,  5},
  66.        {-3,  0, -3},
  67.        {-3, -3, -3} };
  68.  
  69. short kirsch_mask_1[3][3] =  {
  70.        {-3,  5,  5},
  71.        {-3,  0,  5},
  72.        {-3, -3, -3} };
  73.  
  74. short kirsch_mask_2[3][3] =  {
  75.        {-3, -3,  5},
  76.        {-3,  0,  5},
  77.        {-3, -3,  5} };
  78.  
  79. short kirsch_mask_3[3][3] =  {
  80.        {-3, -3, -3},
  81.        {-3,  0,  5},
  82.        {-3,  5,  5} };
  83.  
  84. short kirsch_mask_4[3][3] =  {
  85.        {-3, -3, -3},
  86.        {-3,  0, -3},
  87.        { 5,  5,  5} };
  88.  
  89. short kirsch_mask_5[3][3] =  {
  90.        {-3, -3, -3},
  91.        { 5,  0, -3},
  92.        { 5,  5, -3} };
  93.  
  94. short kirsch_mask_6[3][3] =  {
  95.        { 5, -3, -3},
  96.        { 5,  0, -3},
  97.        { 5, -3, -3} };
  98.  
  99. short kirsch_mask_7[3][3] =  {
  100.        { 5,  5, -3},
  101.        { 5,  0, -3},
  102.        {-3, -3, -3} };
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.    /* masks for prewitt operator */
  110.  
  111. short prewitt_mask_0[3][3] =  {
  112.        { 1,  1,  1},
  113.        { 1, -2,  1},
  114.        {-1, -1, -1} };
  115.  
  116. short prewitt_mask_1[3][3] =  {
  117.        { 1,  1,  1},
  118.        { 1, -2, -1},
  119.        { 1, -1, -1} };
  120.  
  121. short prewitt_mask_2[3][3] =  {
  122.        { 1,  1, -1},
  123.        { 1, -2, -1},
  124.        { 1,  1, -1} };
  125.  
  126. short prewitt_mask_3[3][3] =  {
  127.        { 1, -1, -1},
  128.        { 1, -2, -1},
  129.        { 1,  1,  1} };
  130.  
  131. short prewitt_mask_4[3][3] =  {
  132.        {-1, -1, -1},
  133.        { 1, -2,  1},
  134.        { 1,  1,  1} };
  135.  
  136. short prewitt_mask_5[3][3] =  {
  137.        {-1, -1,  1},
  138.        {-1, -2,  1},
  139.        { 1,  1,  1} };
  140.  
  141. short prewitt_mask_6[3][3] =  {
  142.        {-1,  1,  1},
  143.        {-1, -2,  1},
  144.        {-1,  1,  1} };
  145.  
  146. short prewitt_mask_7[3][3] =  {
  147.        { 1,  1,  1},
  148.        {-1, -2,  1},
  149.        {-1, -1,  1} };
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.    /* masks for sobel operator */
  157.  
  158. short sobel_mask_0[3][3] =  {
  159.        { 1,  2,  1},
  160.        { 0,  0,  0},
  161.        {-1, -2, -1} };
  162.  
  163. short sobel_mask_1[3][3] =  {
  164.        { 2,  1,  0},
  165.        { 1,  0, -1},
  166.        { 0, -1, -2} };
  167.  
  168. short sobel_mask_2[3][3] =  {
  169.        { 1,  0, -1},
  170.        { 2,  0, -2},
  171.        { 1,  0, -1} };
  172. short sobel_mask_3[3][3] =  {
  173.        { 0, -1, -2},
  174.        { 1,  0, -1},
  175.        { 2,  1,  0} };
  176.  
  177. short sobel_mask_4[3][3] =  {
  178.        {-1, -2, -1},
  179.        { 0,  0,  0},
  180.        { 1,  2,  1} };
  181.  
  182. short sobel_mask_5[3][3] =  {
  183.        {-2, -1,  0},
  184.        {-1,  0,  1},
  185.        { 0,  1,  2} };
  186.  
  187. short sobel_mask_6[3][3] =  {
  188.        {-1,  0,  1},
  189.        {-2,  0,  2},
  190.        {-1,  0,  1} };
  191.  
  192. short sobel_mask_7[3][3] =  {
  193.        { 0,  1,  2},
  194.        {-1,  0,  1},
  195.        {-2, -1,  0} };
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.   /**************************************************
  203.   *
  204.   *   detect_edges(...
  205.   *
  206.   *   This function detects edges in an area of one
  207.   *   image and sends the result to another image
  208.   *   on disk.  It reads the input image from disk,
  209.   *   calls a convolution function, and then writes
  210.   *   the result out to disk.  If needed, it
  211.   *   allocates space on disk for the output image.
  212.   *
  213.   ***************************************************/
  214.  
  215.  
  216.  
  217.  
  218. detect_edges(in_name, out_name, the_image, out_image,
  219.              il, ie, ll, le, detect_type, threshold,
  220.              high)
  221.    char   in_name[], out_name[];
  222.    int    detect_type, high, il, ie,
  223.           ll, le, threshold;
  224.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  225.  
  226. {
  227.    int    i, j, k, length, width;
  228.    struct tiff_header_struct image_header;
  229.  
  230.  
  231.    create_file_if_needed(in_name, out_name, out_image);
  232.  
  233.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  234.  
  235.    read_tiff_header(in_name, &image_header);
  236.  
  237.    perform_convolution(the_image, out_image,
  238.                        detect_type, threshold,
  239.                        &image_header, high);
  240.  
  241.    fix_edges(out_image, 1);
  242.  
  243.    write_array_into_tiff_image(out_name, out_image,
  244.                                il, ie, ll, le);
  245. }  /* ends detect_edges */
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.      /**********************************************************
  254.      *
  255.      *   perform_convolution(...
  256.      *
  257.      *   This function performs convolution between the input
  258.      *   image and 8 3x3 masks.  The result is placed in
  259.      *   the out_image.
  260.      *
  261.      ********************************************************/
  262.  
  263. perform_convolution(image, out_image,
  264.                     detect_type, threshold,
  265.                     image_header, high)
  266.    short image[ROWS][COLS],
  267.          out_image[ROWS][COLS];
  268.    int   detect_type, high, threshold;
  269.    struct tiff_header_struct *image_header;
  270. {
  271.  
  272.    int a,
  273.        b,
  274.        i,
  275.        is_present,
  276.        j,
  277.        sum;
  278.  
  279.    short  mask_0[3][3],
  280.           mask_1[3][3],
  281.           mask_2[3][3],
  282.           mask_3[3][3],
  283.           mask_4[3][3],
  284.           mask_5[3][3],
  285.           mask_6[3][3],
  286.           mask_7[3][3],
  287.           max,
  288.           min,
  289.           new_hi,
  290.           new_low;
  291.  
  292.  
  293.    setup_masks(detect_type, mask_0, mask_1,
  294.                mask_2, mask_3, mask_4, mask_5,
  295.                mask_6, mask_7);
  296.  
  297.    new_hi  = 250;
  298.    new_low = 16;
  299.    if(image_header->bits_per_pixel == 4){
  300.        new_hi  = 10;
  301.        new_low = 3;
  302.    }
  303.  
  304.    min = 0;
  305.    max = 255;
  306.    if(image_header->bits_per_pixel == 4)
  307.       max = 16;
  308.  
  309.      /* clear output image array */
  310.    for(i=0; i<ROWS; i++)
  311.       for(j=0; j<COLS; j++)
  312.          out_image[i][j] = 0;
  313.  
  314.    printf("\n ");
  315.  
  316.    for(i=1; i<ROWS-1; i++){
  317.       if( (i%10) == 0) printf("%3d", i);
  318.       for(j=1; j<COLS-1; j++){
  319.  
  320.  
  321.          /* Convolve for all 8 directions */
  322.  
  323.          /* 0 direction */
  324.  
  325.       sum = 0;
  326.       for(a=-1; a<2; a++){
  327.          for(b=-1; b<2; b++){
  328.             sum = sum + image[i+a][j+b] *
  329.                   mask_0[a+1][b+1];
  330.          }
  331.       }
  332.          if(sum > max) sum = max;
  333.          if(sum < 0)   sum = 0;
  334.             /* Correction 12-27-92
  335.                see file header for
  336.                details. */
  337.       if(sum > out_image[i][j])
  338.          out_image[i][j]   = sum;
  339.  
  340.  
  341.          /* 1 direction */
  342.  
  343.       sum = 0;
  344.       for(a=-1; a<2; a++){
  345.          for(b=-1; b<2; b++){
  346.             sum = sum + image[i+a][j+b] * mask_1[a+1][b+1];
  347.          }
  348.       }
  349.          if(sum > max) sum = max;
  350.          if(sum < 0)   sum = 0;
  351.             /* Correction 12-27-92
  352.                see file header for
  353.                details. */
  354.       if(sum > out_image[i][j])
  355.          out_image[i][j]   = sum;
  356.  
  357.  
  358.          /* 2 direction